﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using SlamCms.Common;
using System.Data;
using System.ServiceModel;
using System.ServiceModel.Channels;
using System.Text.RegularExpressions;
using SlamCms.SharePointServices.Authentication;
using SlamCms.SharePointServices.Configuration;
using SlamCms.SharePointServices.Search;

namespace SlamCms.SharePointServices
{
	public class SearchService
	{
		private static Regex _selectPattern = new Regex("^select(.*?)from", RegexOptions.Singleline | RegexOptions.IgnoreCase);
		public static ServiceResponse<DataTable> GetRelevantResults(string siteUrl, string[] fields, string[] scopes, string searchTerm)
		{	
			string scopeText = "";
			foreach(string scope in scopes) {
			scopeText = String.Format(@"(""SCOPE""='{0}') OR ", scope);
			}
			scopeText = scopeText.Substring(0, scopeText.Length - 4);
			string queryText = String.Format(@"Select {0} FROM Scope() WHERE FREETEXT(DefaultProperties, '{1}')  AND ({2}) ORDER BY ""Rank"" DESC", String.Join(", ", fields), searchTerm, scopeText);
			return GetRelevantResults(siteUrl, queryText);
		}

		public static ServiceResponse<DataTable> GetRelevantResults(string siteUrl, string queryText)
		{
			var client = ServiceClients.GetSearchServiceClient(siteUrl);
			bool usesClaimsAuthentication = false;
			ClaimsAuthenticationType claimsType = ClaimsAuthenticationType.Ntlm;
			if (!String.IsNullOrEmpty(ConfigurationManager.Environment.NetworkCredential.ClaimsAuthenticationType))
			{
				claimsType = (ClaimsAuthenticationType)Enum.Parse(typeof(ClaimsAuthenticationType), ConfigurationManager.Environment.NetworkCredential.ClaimsAuthenticationType);
				usesClaimsAuthentication = true;
			}

			OperationContextScope operationScope = new OperationContextScope(client.InnerChannel);

			if (usesClaimsAuthentication)
			{
				var httpRequestProperty = new HttpRequestMessageProperty();
				httpRequestProperty.Headers.Add("X-FORMS_BASED_AUTH_ACCEPTED", "f");
				OperationContext.Current.OutgoingMessageProperties[HttpRequestMessageProperty.Name] = httpRequestProperty;
			}
			QueryPacket queryPacket = new QueryPacket();
			queryPacket.Query.QueryText = queryText;
			queryPacket.Query.IncludeSpecialTermsResults = false;

			//Parse Properties from queryText
			string selectColumns = "";
			foreach (Match selectMatch in _selectPattern.Matches(queryText))
			{
				selectColumns = Regex.Replace(selectMatch.Groups[1].Value, "\\s", "");
				break;
			}

			if (!selectColumns.IsNullOrEmpty())
			{
				foreach (string property in selectColumns.Split(','))
				{
					queryPacket.Query.Properties.Add(property);
				}
			}

			DataSet resultSet = client.QueryEx(queryPacket.ToString());

			DataTable relevantResultTable = new DataTable();
			if (resultSet.Tables.Contains("RelevantResults"))
			{
				relevantResultTable = resultSet.Tables["RelevantResults"];
			}

			operationScope.Dispose();

			ServiceResponse<DataTable> response = new ServiceResponse<DataTable>();
			response.Response = relevantResultTable;
			return response;
		}
	}
}
